package irio.pythcal;



public class Particle implements Comparable {
	public float mass = 1.0f;
	public float radius = 1.0f;
	public float heat = 1.0f;
	public float angle = 0.0f;
	public float angleStart = 0.0f;
	
	public Vec P = new Vec();
	public Vec V = new Vec();
	public Vec A = new Vec();
	public Vec rot = new Vec();
	
	public final void move(final float dt) {
		V = V.add(A.mul(dt));
		P = P.add(V.mul(dt));
		A.set(0, 0, 0);
		heat*=0.95;
		if (heat<1.0f) heat=1.0f;
		heat=(float)Math.min(5.0, heat);

	}
	public final void gravity(final Particle o, final float g, final float e) {
		Vec force = P.sub(o.P);
		float r = force.len();
		if (r <(radius+o.radius))
			return; // gravitationally within each other
		//if (r >(5*radius))
		///	return; // gravitationally within each other
		force.normDirect();
		force.mulDirect(-g  * o.mass / (r * r + e * e) );
		A.addDirect(force);
	}
	
	public final void crash(final Particle o) {
		Vec dir = (P.sub(o.P));
		float len = dir.len();
		if (len <(radius+o.radius)) {
			dir.normDirect();

			float ms = (mass+o.mass);
			Vec Vp = V.mul((mass-o.mass)/ms).add(o.V.mul((2*o.mass/ms)));
			Vec oVp = V.mul((2*mass)/ms).add(o.V.mul(((o.mass-mass)/ms)));
			

			V = Vp.mul(0.98f);
			o.V = oVp.mul(0.98f);

			float l = o.V.len() + V.len();
			P = o.P.add(dir.mul(radius+o.radius));
			heat+=0.05f*l;
			o.heat+=0.05f*l;
			
		} 
		
	}

	public final void periodicBox(Vec min, Vec max) {
		Vec size = max.sub(min);
		if (P.x>max.x) P.x-=size.x;
		if (P.y>max.y) P.y-=size.y;
		if (P.z>max.z) P.z-=size.z;

		if (P.x<min.x) P.x+=size.x;
		if (P.y<min.y) P.y+=size.y;
		if (P.z<min.z) P.z+=size.z;

		
	}
	public final void wallReflect(Vec min, Vec max, float vScale) {
		Vec size = max.sub(min);
		if (P.x>max.x) V.x=-V.x*vScale;
		if (P.y>max.y) V.y=-V.y*vScale;
		if (P.z>max.z) V.z=-V.z*vScale;

		if (P.x<min.x) V.x=-V.x*vScale;
		if (P.y<min.y) V.y=-V.y*vScale;
		if (P.z<min.z) V.z=-V.z*vScale;
	}
	public int compareTo(Object o) {
		 if (this.P.getRad()<= ((Particle)o).P.getRad())
	            return 1;
	        else 
	            return -1;
	}
	
}
